Shader "Lch/LeafPhong"
{
    Properties
    {
        [Lch2D] [MainTexture] _BaseMap("Albedo", 2D) = "white" {}
        
        [HideInInspector] _EditingTexture("_EditingTexture", 2D) = "white" {}
        [HDR][MainColor] _BaseColor("Color", Color) = (1,1,1,1)
        _Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
        _BumpScale("Scale", Float) = 1.0
        _BumpMap("Normal Map", 2D) = "bump" {}

 
        [HDR]_SpecularColor("SpecularColor(RGB) Smoothness(A)", Color) = (1,1,1,1)
        [HDR]_EmissionColor("EmissionColor", Color) = (0,0,0,1)

        _SSS("SSS",Range(0,1)) = 0.8
        _Leaf("uv偏移(xy,速度,zw幅度)", Vector) = (50,50,0.00,0.00)
        [LCHEnum(LCHblendlModel)] _bendModel("混合模式", Int) = 0

	    [Toggle(_ALPHATEST_ON)]_ALPHATEST_ON("透明剔除",Int) = 0
		 
  
		[Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend("源混合 SrcBlend", Float) = 1
		[Enum(UnityEngine.Rendering.BlendMode)] _DstBlend("目标混合 DstBlend", Float) = 0
		[Enum(Off, 0, On, 1)]_ZWrite("深度写_ZWrite", float) = 1
		[Enum(UnityEngine.Rendering.CullMode)]_CullMode("剔除模式", float) = 2

		_OffsetFactor("双材质防穿插,越小越前", Float) = 0
    }
    SubShader
    {
        Tags
        {
            "RenderPipeline"="UniversalPipeline"
            "RenderType"="Opaque"
            "Queue"="Geometry"
        }

        Pass
        {

             Name "ForwardLit"
            Tags{"LightMode" = "UniversalForward"}

            Blend[_SrcBlend][_DstBlend]
            ZWrite[_ZWrite]
            Cull[_Cull]
            HLSLPROGRAM

            // GPU Instancing
            #pragma multi_compile_instancing

            #pragma shader_feature_local_fragment _ALPHATEST_ON

            #define _LIGHT_LAYERS
            #define   _SHADOWS_SOFT
            #define _MAIN_LIGHT_SHADOWS_CASCADE
            #define    _ADDITIONAL_LIGHTS
   
 
            #pragma multi_compile   _  LIGHTMAP_ON 
            //#define _SPECGLOSSMAP
            
            
            //_ADDITIONAL_LIGHT_SHADOWS _LIGHT_LAYERS _MAIN_LIGHT_SHADOWS_CASCADE _SHADOWS_SOFT
            #define _NORMALMAP  

            #define MAIN_LIGHT_CALCULATE_SHADOWS
            #ifdef _NORMALMAP
            #define REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR 

            #endif

     
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary\Lighting.hlsl"
          
 

            #include "lch_global_buffer.hlsl"
            #include "LeafPhongInput.hlsl"

            #define CUSTOM_VERTEX_PARAM 
            #include "lch_urp_com.hlsl"
 
             #include "lch_weather.hlsl"
            #pragma vertex vert
            #pragma fragment frag
           

           
           void wind_uvs(   inout float2 uv )
	        {
 
		        float s = sin(_Time.x * _Leaf.x);
		        float c = cos(_Time.x * _Leaf.y);
		        float2x2 rotMat = float2x2(c, -s, s, c);
		        uv.xy += mul(rotMat, float2(_Leaf.z, _Leaf.w));
		 
	        }
            
            Varyings vert(Attributes input)
            {
                Varyings output = (Varyings)0;
                UNITY_SETUP_INSTANCE_ID(input);
                UNITY_TRANSFER_INSTANCE_ID(input, output);
                UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
                FillVaryingsData( input, output);
                output.uv = TRANSFORM_TEX(output.uv, _BaseMap);
              
                 wind_uvs(output.uv);

 
                return output;
            }
           
            half3 CalculateBlinnPhong(Light light, InputData inputData )
            {
                half3 attenuatedLightColor = light.color * (light.distanceAttenuation * light.shadowAttenuation);
                half3 baseLight = attenuatedLightColor*  dot(light.direction, inputData.normalWS);
                half3 lightColor = max( baseLight,0) + max( -baseLight,0)*_SSS; 
 
           
                half smoothness = exp2(10 * _SpecularColor.a + 1);

                lightColor += LightingSpecular(attenuatedLightColor, light.direction, inputData.normalWS, inputData.viewDirectionWS, half4(_SpecularColor.rgb, 1), smoothness);
         

                return lightColor;
            }
            half4 frag(Varyings input,bool isFrontFace : SV_IsFrontFace) : SV_Target
            {

                UNITY_SETUP_INSTANCE_ID(input);
                UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);

                float2 uv = input.uv;

                LchSurfaceData surfaceData;
                InitializeLchSurfaceData(input.uv,input.color, surfaceData);

             
                InputData inputData;
                InitializeInputData(input,isFrontFace, surfaceData.normalTS, inputData);

                 Weather(surfaceData, inputData, input.normalWS,input.positionWS);

                half4 shadowMask = CalculateShadowMask(inputData);
    
                half3 albedo = surfaceData.albedo;
 
                AmbientOcclusionFactor aoFactor  ;

                aoFactor.directAmbientOcclusion = 1.0;
                aoFactor.indirectAmbientOcclusion = 1.0;
 
                Light mainLight = GetMainLight(inputData, shadowMask, aoFactor);
 
                half3 ambient = inputData.bakedGI.rgb;
 
                MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI);
                uint meshRenderingLayers = GetMeshRenderingLayer();
                half3 color = half3(0,0,0);
                //自发光
                half3 emission = _EmissionColor.rgb;
                color.rgb += (ambient+emission);
                half4 spColor = _SpecularColor;
               
                if (IsMatchingLightLayer(mainLight.layerMask, meshRenderingLayers))
                {

                    color += CalculateBlinnPhong(mainLight, inputData   );
                   
                }
               
                
               #if defined(_ADDITIONAL_LIGHTS)
           
                uint pixelLightCount = GetAdditionalLightsCount();

 

                #if USE_CLUSTERED_LIGHTING
                for (uint lightIndex = 0; lightIndex < min(_AdditionalLightsDirectionalCount, MAX_VISIBLE_LIGHTS); lightIndex++)
                {
                    Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);
                    if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
                    {
                        color += CalculateBlinnPhong(light, inputData   );
                    }
                }
                #endif

                LIGHT_LOOP_BEGIN(pixelLightCount)
                    Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);
                    if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
                    {
                        color += CalculateBlinnPhong(light, inputData   );
                    }
                LIGHT_LOOP_END
                #endif
                #if defined(_ADDITIONAL_LIGHTS_VERTEX)
                lightingData.vertexLightingColor += inputData.vertexLighting * surfaceData.albedo;
                #endif
                color*=albedo;
               return float4(color,1.0);
            }
            ENDHLSL
        }

         Pass
        {
            Name "ShadowCaster"
            Tags{"LightMode" = "ShadowCaster"}

            ZWrite On
            ZTest LEqual
            ColorMask 0
            Cull[_Cull]

            HLSLPROGRAM
 

  
            #pragma shader_feature_local_fragment _ALPHATEST_ON
            //#pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A

            //--------------------------------------
            // GPU Instancing
            #pragma multi_compile_instancing
            //#pragma multi_compile _ DOTS_INSTANCING_ON
            // -------------------------------------
            // Universal Pipeline keywords

            // This is used during shadow map generation to differentiate between directional and punctual light shadows, as they use different formulas to apply Normal Bias
            //#pragma multi_compile_vertex _ _CASTING_PUNCTUAL_LIGHT_SHADOW

            #pragma vertex ShadowPassVertex
            #pragma fragment ShadowPassFragment

            #pragma multi_compile_vertex _ _ALPHATEST_ON
       
 
            #include "LeafPhongInput.hlsl"
         
            
            #include "Packages/com.unity.render-pipelines.universal/Shaders/ShadowCasterPass.hlsl"
            
            

             
            ENDHLSL
        }

        Pass
        {
            Name "Meta"
            Tags{"LightMode" = "Meta"}

            Cull Off

            HLSLPROGRAM
           
 

            #pragma vertex UniversalVertexMeta
            #pragma fragment UniversalFragmentMetaLitFun

            #pragma shader_feature EDITOR_VISUALIZATION
            //#pragma shader_feature_local_fragment _SPECULAR_SETUP
            #pragma shader_feature_local_fragment _EMISSION
 
            #pragma shader_feature_local_fragment _ALPHATEST_ON
 
            #include "LeafPhongInput.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl"

            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UniversalMetaPass.hlsl"
            half4 UniversalFragmentMetaLitFun(Varyings input) : SV_Target
            {

                LchSurfaceData surfaceData;
                InitializeLchSurfaceData(input.uv,1, surfaceData);
                MetaInput metaInput;
                metaInput.Albedo = surfaceData.albedo.xyz;
                metaInput.Emission = surfaceData.emission;
 
                return UniversalFragmentMeta(input, metaInput);
            }

            ENDHLSL
        }


        Pass
        {
            Name "DepthOnly"
            Tags{"LightMode" = "DepthOnly"}

            ZWrite On
            ColorMask 0
            Cull[_Cull]

            HLSLPROGRAM
 
   

            #pragma vertex DepthOnlyVertex
            #pragma fragment DepthOnlyFragment

            // -------------------------------------
            // Material Keywords
            #pragma shader_feature_local_fragment _ALPHATEST_ON
           // #pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A

            //--------------------------------------
            // GPU Instancing
            #pragma multi_compile_instancing
            //#pragma multi_compile _ DOTS_INSTANCING_ON

            
 
            #include "LeafPhongInput.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl"
            ENDHLSL
        }

        // This pass is used when drawing to a _CameraNormalsTexture texture
        Pass
        {
            Name "DepthNormals"
            Tags{"LightMode" = "DepthNormals"}

            ZWrite On
            Cull[_Cull]

            HLSLPROGRAM
 
 

            #pragma vertex DepthNormalsVertex
            #pragma fragment DepthNormalsFragment

            // -------------------------------------
            // Material Keywords
            #pragma shader_feature_local _NORMALMAP
 
            #pragma shader_feature_local_fragment _ALPHATEST_ON
 

            //--------------------------------------
            // GPU Instancing
            //#pragma multi_compile_instancing
            //#pragma multi_compile _ DOTS_INSTANCING_ON

 
 
            #include "LeafPhongInput.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/Shaders/LitDepthNormalsPass.hlsl"
            ENDHLSL
        }
    }
    FallBack "Hidden/Shader Graph/FallbackError"

    CustomEditor "LCHShaderGUIBase" 
}